#* -coding: utf - 8 -* -
"""
 Copyright 2010 Kruglov M.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
"""

import threading

class BasePlugin(object):
    """Base Plugin class"""

    plugin_type = "base_plugin"
#    name = __name__
    logger = False

    def prePlug(self):
        return True

    def afterPlug(self):
        return True

    def __init__(self,kern):
        self.kern = kern
        self.logMessage = self.kern.logMessage
        self.name = self.__class__.__name__
        if not self.logger:
            self.logger = self.name

class BasePeriodicTask(BasePlugin):

    plugin_type = "periodic_callback"
    timeout = 3
    start_on_plug = 1
    sig_stop = 0

    def onCall(self):
        pass

    def onStop(self):
        pass

class BaseXmppHandler(BasePlugin):
    """Base plugguble XMPP handler"""

    makefirst = 0
    plugin_type = 'xmpp_handler'

    def preOnCall(self,conn,mess):
        self.onCall(conn,mess)

    def onCall(self,conn,mess):
        pass

class BaseKernelPlugin(BasePlugin):
    plugin_type = 'kernel'

class Sheduler(BaseKernelPlugin):
    """Kernel sheduler class, used internally"""

    callbacks = dict()

    class initThread(threading.Thread):

        def __init__(self,obj):
            threading.Thread.__init__(self)
            self.fn = obj.onCall
            self.timeout = obj.timeout
            self.onStop = obj.onStop
            self.finished = threading.Event()

        def run(self):
            while self.go:
                self.finished.wait(self.timeout)
                if not self.finished.is_set():
                    self.fn()

        def start(self):
            self.sigstop_recived = 0
            self.go = 1
            threading.Thread.start(self)

        def stop(self):
            self.onStop()
            self.finished.set()
            self.go = 0
            self.stop_rcvd = 1

    def setCallback(self,obj):
        if obj.name not in self.callbacks:
            self.callbacks[obj.name] = self.initThread(obj)
            return True
        else:
            self.kern.logMessage("task '%s' already registered" % obj.name)
            return False

    def delCallback(self,objname):
        self.stop(objname)
        del self.callbacks[objname]

    def start(self,objname):
        try:
            self.callbacks[objname].start()
            self.kern.logMessage("periodic task '%s' started" % (objname))
        except RuntimeError,e:
            if e == "thread already started":
                self.kern.logMessage("periodic task '%s' already started" % objname,2)

    def stop(self,objname):
        self.callbacks[objname].stop()


################################################################
